#!/usr/bin/env python
#
# MBank.py
# Copyright (C) 2011 Piotr Foltyn
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


import AutoLock
import CommandThread
from Secret import *
import mechanize
import re
import threading
import urllib


_MBANK_URL  = 'https://www.mbank.com.pl/'
_MAIN_URL   = _MBANK_URL + 'frames.aspx'
_LOGON_URL  = _MBANK_URL + 'logon.aspx'
_LOGOUT_URL = _MBANK_URL + 'logout.aspx'
_INVEST_URL = _MBANK_URL + 'investitions.aspx'
_BASKET_URL = _MBANK_URL + 'di_quotation_basket_list.aspx'
_QUOTATIONS_URL = _MBANK_URL + 'di_open_quotations.aspx'


class LogonCommand(CommandThread.Command):
    def execute(self, bank):
        bank.openAndGetParameters(_MBANK_URL, '', '')
        submitStr = bank.prepareFormForSubmission({'Y3VzdG9tZXI='.decode('base64'): Y3VzdG9tZXI,
                                                   'cGFzc3dvcmQ='.decode('base64'): cGFzc3dvcmQ})
        bank.openAndGetParameters(_LOGON_URL, submitStr, '')


class LogoutCommand(CommandThread.Command):
    def execute(self, bank):
        regex = '[\s\S]*<h3 style="margin: 0;">|</h3>[\s\S]*'
        parameters = bank.openAndGetParameters(_LOGOUT_URL, '', regex)


class GetQuotationsSessionIdCommand(CommandThread.Command):
    quotationsSessionId = ''

    def execute(self, bank):
        regex = '[\s\S]*di_quotation_basket_list\.aspx\',\'\',\'POST\',\'|\',[\s\S]*'
        parameters = bank.openAndGetParameters(_INVEST_URL, '', regex)
        submitStr = bank.prepareFormForSubmission({'__PARAMETERS': parameters})
        
        regex = '[\s\S]*di_open_quotations\.aspx\',\'InnerFrame\',\'POST\',\'|\',[\s\S]*'
        parameters = bank.openAndGetParameters(_BASKET_URL, submitStr, regex)
        submitStr = bank.prepareFormForSubmission({'__PARAMETERS': parameters})
        
        regex = '[\s\S]*openBasket\(\'|\',\'[\s\S]*'
        self.quotationsSessionId = bank.openAndGetParameters(_QUOTATIONS_URL, submitStr, regex)


# Do not instantiate this class, use GetBank() below
class _MBank(CommandThread.CommandThread):
    def __init__(self, debug=True):
        super(_MBank, self).__init__()
        self._browser = mechanize.Browser()
        self._browser.set_debug_redirects(debug)
        self._browser.set_debug_responses(debug)
        self._browser.set_debug_http(debug)

    def _handleCommand(self, command):
        command.execute(self)
        command.taskDone()

    def prepareFormForSubmission(self, parametersDict):
        submit = {}
        for form in self._browser.forms():
            submit.update(dict([(control.name, control.value) for control in form.controls]))
        submit.update(parametersDict)
        if None in submit:
            del submit[None]
        return urllib.urlencode(submit.items())

    def openAndGetParameters(self, url, submitStr, regex):
        response = self._browser.open(url + '?', submitStr)
        page = response.read().decode('iso8859-2')
        return re.sub(regex, '', page)


_bankAccessLock = threading.Lock()
_bank = None


def GetBank():
    global _bankAccessLock
    with AutoLock.AutoLock(_bankAccessLock) as lock:
        global _bank
        if None == _bank:
            _bank = _MBank()
            _bank.start()
        return _bank


if __name__ == '__main__':
    bank = GetBank()
    bank.sendCommand(LogonCommand())
    cmd = GetQuotationsSessionIdCommand()
    bank.sendCommand(cmd)
    cmd.wait()
    print cmd.quotationsSessionId
    cmd = LogoutCommand()
    bank.sendCommand(cmd)
    bank.stop()
    bank.join()
